home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.07 Jul 91 / Drivers / MenuMem DRVR.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-03-07  |  6.2 KB  |  245 lines  |  [TEXT/KAHL]

  1. /*------------------------------------------------------------------------------
  2.  
  3. PROGRAM
  4.         MenuMem - A combination INIT/DRVR that displays the amount of
  5.                   free memory in the menu bar.
  6.  
  7. FILE
  8.         “MenuMem DRVR.c”
  9.  
  10. DESCRIPTION
  11.         This file contains all of the code for the DRVR.  In addition to the
  12.         standard Open, Control, and Close routines needed by all DRiVeRs, there
  13.         are two support routines, setup_theMenu() and update_theMenu().  This
  14.         DRiVeR does not support read, write or status calls.
  15.  
  16. HISTORY
  17.         2/14/90    -    DAG    Version .1
  18.  
  19.             Copyright © 1990 Daniel A. Green.  All rights reserved.
  20.  
  21. ------------------------------------------------------------------------------ */
  22.  
  23.  
  24.  
  25. /* --------------------------------- INCLUDE FILES --------------------------- */
  26. #include    "MacTypes.h"
  27. #include    "string.h"
  28. #include    "MenuMgr.h"
  29. #include    <DeviceMgr.h>
  30. #include     <ResourceMgr.h>
  31. #include    "MenuMem.h"
  32.  
  33.  
  34.  
  35. /* ------------------------------ GLOBAL VARIABLES --------------------------- */
  36. LongInt        free_memory = 0;                    /* only need two */
  37. Integer        first_close = TRUE;
  38.  
  39.  
  40.  
  41. /* ---------------------------------  FUNCTIONS  ----------------------------- */
  42. main(p, d, i)
  43. cntrlParam *p;        /*  ptr to parameter block      */
  44. DCtlPtr d;            /*  ptr to device control entry */
  45. int i;                /*  entry point selector          */
  46. {
  47.     Integer    theErr;
  48.  
  49.     if (d->dCtlStorage == 0) {                    /* couldn’t get our storage */
  50.         if (i == 0)
  51.             CloseDriver(d->dCtlRefNum);
  52.         return(noErr);
  53.     }
  54.  
  55.     switch (i) {                                /* handle the request: */
  56.         case 0:                                    /*      open        */
  57.             theErr = OpenDRVR(d, p);                           
  58.         break;    
  59.         case 2:                                    /*      control     */
  60.             theErr = ControlDRVR(d, p); 
  61.         break;    
  62.         case 4:                                    /*      close       */
  63.             theErr = CloseDRVR(d, p);
  64.         break;    
  65.         default: 
  66.             theErr = noErr;
  67.         break;
  68.     }
  69.     
  70.     return(theErr);
  71. };
  72.  
  73.  
  74.  
  75. /*******************************************************************************
  76.   OpenDRVR
  77.  *    This routine resets the dCtlFlags, dCtlDelay and dCtlMenu fields of the
  78.  *    DCtlPtr associated with the DRiVeR.
  79.  *
  80.  *******************************************************************************/
  81.  
  82. OpenDRVR(d, p)
  83. DCtlPtr d;
  84. cntrlParam *p;
  85. {
  86.  
  87. /* Don’t need to respond to Read, Write, or Status calls */
  88.     d->dCtlFlags &= ~(dReadEnable | dWritEnable | dStatEnable);
  89. /* but we do need time */
  90.     d->dCtlFlags |= dNeedTime | dNeedGoodBye;    /* to update the menus */
  91.     d->dCtlDelay = 300;                            /*    Every 5 seconds    */
  92.     d->dCtlMenu = OWNEDRSRCID(d->dCtlRefNum);
  93.  
  94. return(noErr);
  95. };
  96.  
  97.  
  98.  
  99. /*******************************************************************************
  100.   setup_theMenu
  101.  *    Creates a menu for which the title is the amount of free memory in the
  102.  *    application heap (in K), the first menu item is the number of free bytes in
  103.  *    the Application Heap (disabled), the second menu item is the number of free
  104.  *    bytes in the System Heap (disabled).  The fourth menu item, when chosen will
  105.  *    compact memory and purge all purgeable blocks from the application (read 
  106.  *    current) heap by calling the MaxMem trap.
  107.  *
  108.  *******************************************************************************/
  109.  
  110. void setup_theMenu(d)
  111. DCtlPtr    d;
  112. {
  113.     char        *menuTitle;
  114.     LongInt        fm;
  115.     MenuHandle    theMenu;
  116.     THz         saved_zone;
  117.     Str255        fmStr, item1, item2;
  118.  
  119.     fm = FreeMem() / 1024;
  120.     NumToString(fm, &fmStr);
  121.     menuTitle = strcat( PtoCstr( (char *) &fmStr), "K");
  122.     theMenu = NewMenu(d->dCtlMenu, CtoPstr(menuTitle));
  123.     InsertMenu(theMenu, 0);                        /* Add menu to the menu list */
  124.  
  125.     saved_zone = GetZone();                        /* Save the current zone */
  126.  
  127.                                                 /* Setup the first menu item */
  128.     strcpy((char *) &item1, "(Application Heap: ");
  129.     SetZone( ApplicZone() );
  130.     fm = FreeMem();
  131.     NumToString(fm, &fmStr);
  132.     AppendMenu(theMenu,CtoPstr(strcat((char *) &item1, PtoCstr((char *) &fmStr))));
  133.  
  134.                                                 /* Setup the second menu item */
  135.     strcpy((char *) item2, "(System Heap: ");
  136.     SetZone( SystemZone() );
  137.     fm = FreeMem();
  138.     NumToString(fm, &fmStr);
  139.     AppendMenu(theMenu,CtoPstr(strcat((char *) &item2, PtoCstr((char *) &fmStr))));
  140.  
  141.                                                 /* Set up remaining menu items */
  142.     AppendMenu(theMenu, "\P(-" );
  143.     AppendMenu(theMenu, "\PCompact Memory" );
  144.  
  145.     SetZone(saved_zone);
  146.     DrawMenuBar();
  147. };
  148.  
  149.  
  150.  
  151. /*******************************************************************************
  152.   update_theMenu
  153.  *    Delete the DRiVeRs current menu and create a new one if the amount of free
  154.  *    memory has changed since the last call or we don’t have a menu in the
  155.  *    current menu bar.
  156.  *
  157.  *******************************************************************************/
  158.  
  159. update_theMenu(d)
  160. DCtlPtr    d;
  161. {
  162.     Boolean        not_installed;
  163.     LongInt        fm;
  164.     MenuHandle    theMenu;
  165.  
  166.     not_installed = ( (theMenu = GetMHandle(d->dCtlMenu)) == NULL );
  167.     fm = FreeMem() / 1024;
  168.     if ( not_installed || (free_memory != fm) ) {
  169.         free_memory = fm;
  170.         if ( theMenu ) {
  171.             DeleteMenu(d->dCtlMenu);
  172.             DisposeMenu(theMenu);
  173.         }
  174.         setup_theMenu(d);
  175.     }
  176.     return(noErr);
  177. };
  178.  
  179.  
  180.  
  181. /*******************************************************************************
  182.   ControlDRVR
  183.  *    This routine will be called periodically to update the menu and to handle
  184.  *    the case when our one menu item is chosen.
  185.  *
  186.  *******************************************************************************/
  187.  
  188. ControlDRVR(d, p)
  189. DCtlPtr d;
  190. cntrlParam *p;
  191. {
  192.     Integer    theErr;
  193.     Size    grow, lcf_block;
  194.  
  195.     switch (p->csCode) {
  196.         case accMenu:  
  197.             lcf_block = MaxMem(&grow);
  198.             theErr = update_theMenu(d);
  199.         break;
  200.  
  201.         case accRun:                            /* periodicEvent */
  202.             theErr = update_theMenu(d);
  203.         break;
  204.  
  205.         case goodBye:  
  206.             theErr = CloseDRVR(d, p);
  207.         break;
  208.  
  209.         default: 
  210.             theErr = noErr;
  211.         break;
  212.     }
  213.  
  214.     return(theErr);
  215. };
  216.  
  217.  
  218.  
  219. /*******************************************************************************
  220.   CloseDRVR
  221.  *    Whenever we get a close request, we’ll always return an error so we won’t be
  222.  *    closed (This method will not work on 64K ROMs).
  223.  *    NOTE:  The first time we get a goodbye kiss will be after all INITS have
  224.  *    executed.  The Menu Manager has not been initialized at this time so no
  225.  *    calls can be made yet (We don’t have a menu at this point anyway).
  226.  *
  227.  *******************************************************************************/
  228.  
  229. CloseDRVR(d, p)
  230. DCtlPtr     d;
  231. cntrlParam *p;
  232. {
  233.     MenuHandle    theMenu;
  234.  
  235.     if ( !first_close ) {
  236.         if (theMenu = GetMHandle(d->dCtlMenu)) {
  237.             DeleteMenu(d->dCtlMenu);
  238.             DisposeMenu(theMenu);
  239.         }
  240.     }
  241.     first_close = FALSE;
  242.     return(closeErr);
  243. };
  244.  
  245.